package com.hmjk.health.background.data;

import java.util.Calendar;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.text.format.Time;
import android.util.Log;
import com.hmjk.health.HealthApp;
import com.hmjk.health.background.DataManager;
import com.hmjk.health.background.DatabaseHelper;
import com.hmjk.health.background.NetService;
import com.hmjk.health.background.data.DataUpdated;
import com.hmjk.health.util.HEALTH_KEY;
import com.hmjk.health.util.GlycoseData;


public class GlycoseDataUpdated extends DataUpdated{
	private static String TAG = GlycoseDataUpdated.class.getSimpleName();
	//public static final String TYPE_FAMILY = "family";
	//public static final String TYPE_USER = "user";
	//public static final String TYPE_ALL = "all";
	private final static int QUERY_PAGE_SIZE = 50;
	private boolean working = false;	
	private static HashMap<String,GlyDataGet> mMap = new HashMap<String,GlyDataGet>();
	private int netindex = 0;
	
	public class GLY_TIME{
		long newest = 0;
		long update = 0;
	}
		
	public class GlyDataGet{
		
		public HEALTH_KEY gly_key;   //tid + subcode
		public GLY_TIME gly_time = new GLY_TIME();  //time in db, time update 
		
		public long reqStartTime=0,reqEndTime=0;    //recent req
		public int pageIndex = 1;
		public boolean getNext = false;
		
		public GlyDataGet(String _tid, String _subcode)
		{
			gly_key = new HEALTH_KEY(_tid,_subcode);
		}
		
		@Override
		public String toString(){
			return ("GlyDataGet(key:"+gly_key.tid+","+gly_key.subcode+",pageIndex:"+pageIndex+",getNext:"+getNext+")");
		}
	}
	
	private void logd(String info){
		Log.d(TAG, info);
	}
	
	private void loge(String info){
		Log.d(TAG, info);
	}
	
	public GlycoseDataUpdated(HealthApp app, DataManager dm) {
		super(app, dm);
		//UPDATE_TIME = 2 * 60 * 1000;
	}

	@Override
	public void setUserData(Object data) {
		// TODO Auto-generated method stub
		reqTime = 0;
	}

	@Override
	public long delay() {
      return -1;
	}
	
	private void doRequest(GlyDataGet dataGet){		//index = -1 get all
		
		int count = QUERY_PAGE_SIZE;//mApp.getGlycoseQueryLatestMaxCount();	
		String uid = mApp.getUID();
		
		Intent si = new Intent(NetService.GET_DATA_ACTION);
		si.putExtra("sub_act", NetService.GET_GLYCOSE_DATA_PERIOD);
		si.putExtra("uid", uid);
		si.putExtra("tid", dataGet.gly_key.tid);
		si.putExtra("subcode", dataGet.gly_key.subcode);
		si.putExtra("starttime", dataGet.reqStartTime);
		si.putExtra("endtime", dataGet.reqEndTime);
		si.putExtra("pageindex", Integer.toString(dataGet.pageIndex));	
		si.putExtra("pagesize", String.valueOf(count));	
		
		Time t = new Time();
		t.setToNow();
		String stamp = "GET_GLYCOSE_DATA_PERIOD" + t.toString() + netindex; 
		logd("doRequest"+dataGet+",stamp="+stamp);
		si.putExtra("stamp",stamp);
		mApp.addNetHandler(stamp,mDm.getBackGroundHandler());
		mApp.startService(si);
		netindex ++;
		netindex = netindex%255;
	}

	@Override
	public boolean grab() {
		return false;
	}

	@Override
	public boolean grabByUser() {
		return false;
	}
	
	@Override
	public boolean grabByUserWithSingleArgs(Object args){
		DatabaseHelper dh = mDm.getDatabaseHelper();
		if(args == null)
			return false;
		
		HEALTH_KEY arg = (HEALTH_KEY)args;

		String uid = mApp.getUID();
		
		if(uid == null)
			return false;
			
		String key = arg.tid + "_" + arg.subcode;
		logd("grabByUserWithSingleArgs key="+key);
		GlyDataGet dGet = mMap.get(key); 

		long curMs = System.currentTimeMillis();
		if(dGet != null){
			GLY_TIME tinfo = dGet.gly_time;
			
			if(dGet.getNext == true){
				logd("grabByUserWithSingleArgs return for getNext="+dGet.getNext);
				return false;
			}
			
			if((curMs - tinfo.update) < MIN_QUERY_DUR * 1000){
				logd("grabByUserWithSingleArgs wait for " + MIN_QUERY_DUR + "s");
				return false;
			}
		}else{
			dGet = new GlyDataGet(arg.tid, arg.subcode);
			mMap.put(key, dGet);
			String table = dh.checkGlycosyTable(arg.tid,arg.subcode);
			if(table != null){
				Cursor c = dh.getNewestOneInGlycosyTable(table);
				if(c.getCount() > 0){
					c.moveToNext();
					dGet.gly_time.newest = c.getLong(c.getColumnIndex(DatabaseHelper.GLYCOSY_RECORD_TIME));
				}
				c.close();
			}
			dh.closeDB();			
		}
		
		dGet.pageIndex = 1;
		dGet.reqEndTime = System.currentTimeMillis();
		if(dGet.gly_time.newest == 0)
		{
			long day = mApp.getGlycoseQueryLatestMaxDays();
			long tmp = (long)day*24*60*60*1000;
			dGet.gly_time.newest = dGet.reqEndTime - tmp;	
		}
		dGet.reqStartTime = dGet.gly_time.newest;		
		dGet.getNext = true;
		doRequest(dGet);
		dGet.gly_time.update = curMs;
		
		return true;
	}	
	
	private boolean checkBgtypeValid(String type){
		try {
			int iType = Integer.parseInt(type);
			if((iType >= 1) && (iType <= 8)){
				return true;
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	@Override
	public void receive(String stamp, String sjson) {
		DatabaseHelper dh = mDm.getDatabaseHelper();
		if(dh == null)
			return;
		
		if(stamp.startsWith("GET_GLYCOSE_DATA_PERIOD") == false)
			return;
		
		if(sjson != null){
			boolean isFinish = false;
			boolean update = false;
			long earliest = 0;
			String tid = "";
			String subcode = "";
			try {
				JSONObject json = new JSONObject(sjson);
				int code = json.getInt("code");
				JSONObject sd = json.getJSONObject("senddata");
				if(sd != null){
					tid = sd.getString("tid");
					subcode = sd.getString("subcode");	
				}
				String key = tid + "_" + subcode;
				logd("received: key="+key + " code="+code);
				GlyDataGet dGet = mMap.get(key);
				if(code == 200){
					String state = json.getString("state");
					if(state.equalsIgnoreCase("00")){
						JSONObject recdata = json.getJSONObject("recdata");
						if(recdata != null){
							String table = dh.checkGlycosyTable(tid, subcode);
							if(table == null){
								table = dh.createGlycosyTable(tid, subcode);
							}
							
							if(table == null){
								loge("no table for " + tid + subcode);
								return;
							}
							
							if(recdata.has("bgdata")){
								JSONArray array = recdata.getJSONArray("bgdata");
								int len = array.length();
								long newest = dGet.gly_time.newest;
								
								if(len > 0)
									update = true;
								
								logd("GET SIZE = " + len);
								if(len < QUERY_PAGE_SIZE){
									logd("NO DATA MORE");
									dGet.getNext = false;
									isFinish = true;
								}else{
									logd("DATA MORE");
									dGet.getNext = true;
									isFinish = false;
								}								
								/*long count = dh.checkCountInTable(table);
								int max = mApp.getGlycoseQueryLatestMaxCount();
								if((len + count) > max){
									long delta = Math.min(len + count - max, count);
									dh.removeOldFromLocationTable(table, (len + count - max));
								}*/
								
								for(int i = 0; i <= len-1; i++){
									JSONObject o = array.getJSONObject(i);
									
									String bgvalue = o.getString("bgvalue");
									if(bgvalue.trim().isEmpty() || bgvalue.equalsIgnoreCase("NULL")){
										continue;
									}
									
									String bgtype = o.getString("bgtype");
									if(bgtype.trim().isEmpty() || bgtype.equalsIgnoreCase("NULL")){
										continue;
									}
									if(checkBgtypeValid(bgtype) == false){
										continue;
									}
									
									ContentValues cv = new ContentValues();
									cv.put(DatabaseHelper.GLYCOSY_TYPE, bgtype.trim());
									cv.put(DatabaseHelper.GLYCOSY_VALUE,bgvalue.trim());
                                    
									long time = o.getLong("recordtime");
									cv.put(DatabaseHelper.GLYCOSY_RECORD_TIME, time);
									
									dh.addOne2Table(table, cv);
									if(time > newest){
										newest = time;
									}
									
									if(i == len - 1)
										earliest = time;
								}
								
								if(newest > 0){
									dGet.gly_time.newest = newest;
								}
							}
							else
							{
								logd("2 NO DATA MORE");
								dGet.getNext = false;
								isFinish = true;
							
							}
							
							dh.closeDB();
						}
					}
					else
					{
						logd("receive: state err");
						dGet.getNext = false;
						isFinish = true;
					}
					
					if(dGet.getNext)
					{
						dGet.pageIndex++;
						this.doRequest(dGet);
						logd("receive: dGet="+dGet);
					}					
				}else{
					isFinish = true;
					logd("receive: code err");
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block				
				isFinish = true;
				e.printStackTrace();
				logd("json err");
			}

			Intent i = new Intent(DataManager.DATA_UPDATE_ACTION);
			i.putExtra("type",DataManager.F_GLYCOSE_DATA);			
			i.putExtra("tid", tid);
			i.putExtra("subcode", subcode);
			i.putExtra("state", update);
			i.putExtra("isFinish", isFinish);
			i.putExtra("earliest", earliest);
			mApp.sendBroadcast(i);
			
			if(isFinish == true)
			{
				String key = tid + "_" + subcode;
				GlyDataGet dGet = mMap.get(key);
				dGet.getNext = false;
				logd("receive: dGet="+dGet + "isFinish="+isFinish);
			}
			
		}
		
	}
	
	@Override
	public Object check(String[] arg) {
		if((arg != null) && (arg.length == 4)){
			String tid = arg[0];
			String subcode = arg[1];
			String key = tid + "_" + subcode;
			long start = Long.parseLong(arg[2]);
			long end = Long.parseLong(arg[3]);
			
			DatabaseHelper dh = mDm.getDatabaseHelper();
			if(dh == null)
				return null;
			

			GlyDataGet dGet = mMap.get(key);
				
				String table = null;
				if(dGet == null){
					dGet = new GlyDataGet(tid,subcode);
					table = dh.checkGlycosyTable(tid, subcode);
					if(table != null){
						Cursor c = dh.getNewestOneInGlycosyTable(table);
						if(c.getCount() > 0){
							c.moveToNext();
							dGet.gly_time.newest = c.getLong(c.getColumnIndex(DatabaseHelper.GLYCOSY_RECORD_TIME));
						}
						c.close();
					}
					mMap.put(key, dGet);
				}else{
					table = dh.checkGlycosyTable(tid, subcode);
				}
				
				GlycoseData data = new GlycoseData(tid,subcode);
				data.upTime = dGet.gly_time.update;
				
				if(table == null){
					dh.closeDB();
					return data;
				}
				
				long lateTime = System.currentTimeMillis() -  mApp.getGlycoseQueryLatestMaxDays()*24*60*60*1000;
				Calendar ca = Calendar.getInstance();
				ca.setTimeInMillis(lateTime);
				ca.set(Calendar.MINUTE, 0);
				ca.set(Calendar.SECOND, 0);
				lateTime = ca.getTimeInMillis();				
				dh.removeOldFromGlyDataTable(table, lateTime);
				
				Cursor c = dh.getPeriodItemsInGlycosyTable(table,start,end); //dh.getItemsInTable(table);//
				
				int count = c.getCount();
				
				if(c.getCount() > 0){
					while(c.moveToNext()){

						float value = Float.parseFloat(c.getString(c.getColumnIndex(DatabaseHelper.GLYCOSY_VALUE)));
						long time = c.getLong(c.getColumnIndex(DatabaseHelper.GLYCOSY_RECORD_TIME));
						int type = Integer.parseInt(c.getString(c.getColumnIndex(DatabaseHelper.GLYCOSY_TYPE)));
						data.insertItem(new GlycoseData.GLY_DETAIL(value,time,type));
					}
				}
				c.close();

			dh.closeDB();
			return data;
		}
		return null;
	}

	@Override
	public boolean commit(Object data) {
		return true;
	}

	@Override
	public void release() {
		// TODO Auto-generated method stub
		
	}
}
